﻿using System;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Services;
using System.Runtime.Remoting;

namespace System.ComponentModel {
	public class SingletonAttribute: ProxyAttribute {
		public override MarshalByRefObject CreateInstance(Type serverType) {
			SingletonProxy sp = new SingletonProxy(serverType);
			return (MarshalByRefObject)sp.GetTransparentProxy();
		}
	}

	public class SingletonProxy: RealProxy {
		private static MarshalByRefObject _serverObject = null;

		public SingletonProxy(Type type)
			: base(type) {
		}

		public override IMessage Invoke(IMessage msg) {
			IMessage rm = null;
			if (msg is IConstructionCallMessage) {
				IConstructionCallMessage ctorMsg = (IConstructionCallMessage)msg;

				if (_serverObject == null) {
					SingletonProxy sp = new SingletonProxy(GetProxiedType());
					sp.InitializeServerObject(null);
					_serverObject = sp.GetUnwrappedServer();
				}

				rm = EnterpriseServicesHelper.CreateConstructionReturnMessage(ctorMsg, (MarshalByRefObject)GetTransparentProxy());

			}
			else {
				IMethodCallMessage mcm = (IMethodCallMessage)msg;

				rm = RemotingServices.ExecuteMessage(_serverObject, mcm);
			}

			return rm;
		}
	}
}
